package com.ttg.web.service.Impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.handler.inter.IWriter;
import com.ttg.common.entities.BasePage;
import com.ttg.common.entities.PagesRes;
import com.ttg.common.enums.*;
import com.ttg.common.exception.BaseException;
import com.ttg.common.utils.BigDecimalUtils;
import com.ttg.common.utils.eazypoi.ExcelReportConfig;
import com.ttg.model.dto.CostGradingDTO;
import com.ttg.model.po.CostGradingCutoffBatchPO;
import com.ttg.model.po.CostGradingPO;
import com.ttg.model.po.MerchTradeMonthPO;
import com.ttg.model.pojo.CostManageCostGradingRule;
import com.ttg.model.pojo.CostManageMerchTradeMonth;
import com.ttg.model.vo.*;
import com.ttg.web.dao.CostManageCostGradingRuleDao;
import com.ttg.web.dao.CostManageMerchTradeMonthDao;
import com.ttg.web.service.CostGradingService;
import com.ttg.web.utils.CostGradingUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Description：
 * Author: chenyou
 * Date: 2025/10/16 9:40
 * Company: ttg
 * Copyright: Copyright (c) 2025
 */
@Slf4j
@Service
public class CostGradingServiceImpl implements CostGradingService {

    @Autowired
    private CostManageCostGradingRuleDao costGradingRuleDao;
    @Autowired
    private CostManageMerchTradeMonthDao merchTradeMonthDao;
    private static final Integer PAGE_SIZE = 1000;

    @Override
    public CMAcctCostGradingVO costGrading(CostGradingDTO reqDto) {
        //tbl_cost_manage_cost_grading 按月或者按累计读取数据,按清算成本分组
        //按成本分档范围：统计商户数，贴费成本，日均存款，户数占比，万元补贴水平等......
        Map<Integer,String> ruleMap = getRuleMap();

        MerchTradeMonthPO po = bulidPO(reqDto);
        List<CostManageMerchTradeMonth> list = merchTradeMonthDao.getParam(po);

        //分档保存商户成本数据
        Map<Integer,List<CostManageMerchTradeMonth>> gradingMap = list.stream().collect(Collectors.groupingBy(CostManageMerchTradeMonth::getMtmGradingNo));

        MerchDimTypeEnum merchDimTypeEnum = MerchDimTypeEnum.getByVal(reqDto.getMerchDimType());
        String month = reqDto.getMonth();

        List<CostGradingPO> costGradingPOList = costGradingPOList(gradingMap,list.size());

        //分档1-13小计
        sum1(costGradingPOList,merchDimTypeEnum,month);
        //分档14-20小计
        sum2(costGradingPOList,merchDimTypeEnum,month);
        //分档1-20合计
        sum3(costGradingPOList,merchDimTypeEnum,month);
        //划断分批小计
        List<CostGradingCutoffBatchPO> cutoffBatchList = cutoffBatchList(costGradingPOList,merchDimTypeEnum,month);
        //划断分批1-13小计
        batchSum1(merchDimTypeEnum,month);
        //划断分批14-20小计
        batchSum2(merchDimTypeEnum,month);
        //划断分批1-20合计
        batchSum3(merchDimTypeEnum,month);

        //组装返回vo
        return bulidVO(cutoffBatchList,costGradingPOList,ruleMap,merchDimTypeEnum,month);
    }

    @Override
    public void costGradingMerchExport(CostGradingDTO reqDto, HttpServletResponse response) {
        List<CostManageCostGradingRule> rulelist = costGradingRuleDao.getRulelist();
        if(reqDto.getGradingNo()==null){
            throw new BaseException("分档编号不能为空");
        }
        if(!rulelist.stream().anyMatch(o ->o.getCgrNo().equals(reqDto.getGradingNo()))){
            throw new BaseException("错误的分档编号");
        }
        //设置文件名称等参数
        ExcelReportConfig config = new ExcelReportConfig("成本分档商户明细", "cost_grading_merch_export_");
        ExportParams exportParams = config.setExportParams();
        //设置表头
        List<ExcelExportEntity> entityList = new ArrayList<>();
        // 序号列
        ExcelExportEntity serialNumber = new ExcelExportEntity("序号", "serialNumber");
        serialNumber.setWrap(true);
        entityList.add(serialNumber);
        // 行业列（包含主分类、二级分类）
        ExcelExportEntity industryEntity = new ExcelExportEntity("行业分类", "industry");
        industryEntity.setWrap(true);
        List<ExcelExportEntity> industryList = new ArrayList<>();
        industryList.add(new ExcelExportEntity("主分类", "mainCategory"));
        industryList.add(new ExcelExportEntity("二级分类", "subCategory"));
        industryEntity.setList(industryList);
        entityList.add(industryEntity);
        // 商户信息
        ExcelExportEntity merchantEntity = new ExcelExportEntity("商户情况", "merchantInfo");
        merchantEntity.setWrap(true);
        List<ExcelExportEntity> merchantList = new ArrayList<>();
        merchantList.add(new ExcelExportEntity("商户编码", "mctNo"));
        merchantList.add(new ExcelExportEntity("商户名称", "mctName"));
        merchantList.add(new ExcelExportEntity("客户号", "custNo"));
        merchantEntity.setList(merchantList);
        entityList.add(merchantEntity);
        // 清算成本
        ExcelExportEntity clearCost = new ExcelExportEntity("清算成本", "clearCost");
        // 贴费成本
        ExcelExportEntity repairCost = new ExcelExportEntity("贴费成本", "repairCost");
        // 日均存款
        ExcelExportEntity dayAvgDeposit = new ExcelExportEntity("日均存款", "dayAvgDeposit");
        // 万元补贴水平
        ExcelExportEntity wanYuanRepairRatio = new ExcelExportEntity("万元补贴水平", "wanYuanRepairRatio");
        entityList.add(clearCost);
        entityList.add(repairCost);
        entityList.add(dayAvgDeposit);
        entityList.add(wanYuanRepairRatio);

        //报表数据
        List<Map<String, Object>> dataList = new ArrayList<>();
        IWriter<Workbook> workbookIWriter = ExcelExportUtil.exportBigExcel(exportParams, entityList);
        reqDto.setPageSize(PAGE_SIZE);
        int extCount = 0;
        int total = 0;
        // 每次1000条
        for (int i = 1; i <= 1000; i++) {
            reqDto.setPage(i);
            BasePage<CostManageMerchTradeMonth> page = reqDto.parse();
            MerchTradeMonthPO po = bulidPO(reqDto);
            BasePage<CostManageMerchTradeMonth> index = merchTradeMonthDao.merchExport(page,po);
            PagesRes pagesRes = index.getPagesRes();
            total = (int) pagesRes.getTotalnum();
            extCount += CollectionUtils.isEmpty(index.getList()) ? 0 : index.getList().size();
            dataList.addAll(bulidMerchDataList(index.getList()));
            workbookIWriter.write(dataList);
            dataList.clear();
            if (extCount >= total) {
                break;
            }
        }
        this.workbookExport(workbookIWriter, response, config.getTitle(), config.getFileType());
    }

    public MerchTradeMonthPO bulidPO(CostGradingDTO reqDto){
        MerchTradeMonthPO po = new MerchTradeMonthPO();
        po.setIntervalType(reqDto.getIntervalType());
        po.setLivenessFlag(reqDto.getMerchDimType());
        if(IntervalTypeEnum.月度区间.getValue().equals(reqDto.getIntervalType())) {
            po.setYear(reqDto.getYear());
            po.setMonth(reqDto.getMonth());
        }else if(IntervalTypeEnum.累计区间.getValue().equals(reqDto.getIntervalType())){
            po.setYear(reqDto.getYear());
            po.setLowerBound("01");
            po.setUpperBound(String.format("%02d", reqDto.getMonth()));
            reqDto.setMonth("01_"+String.format("%02d", reqDto.getMonth()));
        }
        //商户明细导出参数
        po.setGradingNo(reqDto.getGradingNo());
        return po;
    }

    public CMAcctCostGradingVO bulidVO(List<CostGradingCutoffBatchPO> cutoffBatchList, List<CostGradingPO> costGradingPOList,Map<Integer,String> ruleMap,MerchDimTypeEnum merchDimTypeEnum,String month){
        CMAcctCostGradingVO vo = new CMAcctCostGradingVO();
        List<CostGradingCutoffBatchVO> batchVOList = new ArrayList<>();
        //按枚举顺序组装成本分档统计
        for(GradingCutOffEnum cutOffEnum : GradingCutOffEnum.values()){
            Optional<CostGradingCutoffBatchPO> optional = cutoffBatchList.stream().filter(o -> o.getCutOffEnum().equals(cutOffEnum)).findFirst();
            if(optional.isPresent()){
                CostGradingCutoffBatchPO cutoffBatchPO = optional.get();
                CostGradingCutoffBatchVO cutoffBatchVO = new CostGradingCutoffBatchVO();
                BeanUtils.copyProperties(cutoffBatchPO,cutoffBatchVO);

                //分档明细行,按划段分批枚举值进行过滤
                List<CostGradingPO> subList = costGradingPOList.stream().filter(o -> o.getCutOffEnum().equals(cutoffBatchPO.getCutOffEnum())).collect(Collectors.toList());
                Integer[] subGradings = cutOffEnum.getCodes();
                List<CostGradingVO> detailListVo = new ArrayList<>();
                for(Integer gradingNo:subGradings){
                    Optional<CostGradingPO> optional1 = subList.stream().filter(o -> o.getGradingNo().equals(gradingNo)).findFirst();
                    if(optional1.isPresent()){
                        CostGradingPO gradingPO = optional1.get();
                        CostGradingVO gradingVO = new CostGradingVO();
                        BeanUtils.copyProperties(gradingPO,gradingVO);
                        gradingVO.setGradingDesc(ruleMap.get(gradingPO.getGradingNo()));
                        detailListVo.add(gradingVO);
                    }else{
                        CostGradingVO gradingVO = new CostGradingVO();
                        gradingVO.setGradingNo(gradingNo);
                        gradingVO.setGradingDesc(ruleMap.get(gradingNo));
                        detailListVo.add(gradingVO);
                    }
                }
                cutoffBatchVO.setDetailListVo(detailListVo);
                batchVOList.add(cutoffBatchVO);
            }else{
                CostGradingCutoffBatchVO cutoffBatchVO = new CostGradingCutoffBatchVO();
                Integer[] subGradings = cutOffEnum.getCodes();
                List<CostGradingVO> detailListVo = new ArrayList<>();
                for(Integer gradingNo:subGradings){
                    CostGradingVO gradingVO = new CostGradingVO();
                    gradingVO.setGradingNo(gradingNo);
                    gradingVO.setGradingDesc(ruleMap.get(gradingNo));
                    detailListVo.add(gradingVO);
                }
                cutoffBatchVO.setCutoff(cutOffEnum.getValue());
                cutoffBatchVO.setDetailListVo(detailListVo);
                batchVOList.add(cutoffBatchVO);
            }

        }


        //小计,总计行
        List<CostGradingSumVO> sumList = new ArrayList<>();
        for(int i=1;i<=3;i++){
            CostGradingSumVO sumVO1 = new CostGradingSumVO();
            sumVO1.setSumFlag("sum" + i);
            sumVO1.setMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum" + i).intValue());
            sumVO1.setRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum" + i));
            sumVO1.setDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum" + i));
            sumVO1.setMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Esum" + i));
            sumVO1.setWanYuanRepairRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Fsum" + i));
            sumVO1.setMctDvgCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Gsum" + i));
            sumVO1.setCreditCardRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Hsum" + i));
            sumVO1.setCutoffRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum" + i));
            sumVO1.setCutoffRepairCostRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Jsum" + i));
            sumVO1.setCutoffDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum" + i));
            sumVO1.setCutoffDayAvgDepositRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Lsum" + i));
            sumVO1.setCutoffMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"M" + i).intValue());
            sumVO1.setCutoffMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"N" + i));
            sumList.add(sumVO1);
        }

        vo.setBatchVOList(batchVOList);
        vo.setSumList(sumList);
        return vo;
    }


    /**
     * 分档规则描述 返回键值对格式：key-value
     */
    public Map<Integer,String> getRuleMap(){
        List<CostManageCostGradingRule> rulelist = costGradingRuleDao.getRulelist();
        Map<Integer,String> ruleMap = new HashMap<>();
        for(CostManageCostGradingRule rule:rulelist){
            String desc = "";
            switch (SymbolEnum.getByVal(rule.getCgrSymbol())){
                case 大于:
                    desc = ">" + rule.getCgrValue() + "%";
                    break;
                case 大于等于:
                    desc = "≥" + rule.getCgrValue() + "%";
                    break;
                case 等于:
                    desc = "=" + rule.getCgrValue() + "%";
                    break;
                case 小于等于:
                    desc = "<=" + rule.getCgrValue() + "%";
                    break;
                case 小于:
                    desc = "<" + rule.getCgrValue() + "%";
                    break;
                case 不等于:
                    desc = "!=" + rule.getCgrValue() + "%";
                    break;
            }
            ruleMap.put(rule.getCgrNo(),desc);
        }
        return ruleMap;
    }

    public List<CostGradingPO> costGradingPOList(Map<Integer,List<CostManageMerchTradeMonth>> gradingMap, Integer totalMctCount){
        //按成本分档范围：统计商户数，贴费成本，日均存款，户数占比，万元补贴水平等......
        List<CostGradingPO> costGradingPOList = new ArrayList<>();
        for(Map.Entry<Integer,List<CostManageMerchTradeMonth>> entry: gradingMap.entrySet()){
            CostGradingPO costGradingPO = new CostGradingPO();

            Integer gradingNo = entry.getKey();
            List<CostManageMerchTradeMonth> sublist = entry.getValue();

            Integer mctCount = sublist.size();
            BigDecimal tradeAmt = BigDecimal.ZERO;
            BigDecimal repairCost = BigDecimal.ZERO;
            BigDecimal dayAvgAmt = BigDecimal.ZERO;
            BigDecimal creditCardAmt = BigDecimal.ZERO;
            for(CostManageMerchTradeMonth vo:sublist){
                tradeAmt = BigDecimalUtils.add(tradeAmt,vo.getMtmTradeAmt());
                repairCost = BigDecimalUtils.add(repairCost,vo.getMtmRepairCost());
                dayAvgAmt = BigDecimalUtils.add(dayAvgAmt,vo.getMtmDayAvgAmt());
                creditCardAmt = BigDecimalUtils.add(creditCardAmt,vo.getMtmCreditTradeAmt());
            }

            BigDecimal mctCountRatio = BigDecimalUtils.div(mctCount,totalMctCount,4);
            BigDecimal wanyuanRepairRatio = BigDecimalUtils.div(BigDecimalUtils.mul(repairCost,10000),tradeAmt,2);
            BigDecimal mctDvgCost = BigDecimalUtils.div(repairCost,mctCount,2);
            BigDecimal creditCardRatio = BigDecimalUtils.div(creditCardAmt,tradeAmt,4);

//            costGradingPO.setCmcgIntervalType(reqDto.getIntervalType());
//            costGradingPO.setCmcgYear(reqDto.getYear());
//            costGradingPO.setCmcgMonth(reqDto.getMonth());
//            costGradingPO.setCmcgMctDimType(reqDto.getMerchDimType());
//            costGradingPO.setCmcgSumFlag("single");
            costGradingPO.setGradingNo(gradingNo);
            //划断分批规则:1-6同批次,7-11同批次,12-13同批次,14-16同批次,17-20同批次
            costGradingPO.setCutOffEnum(getCutOffEnum(gradingNo));
            costGradingPO.setMctCount(mctCount);
            costGradingPO.setTradeAmt(tradeAmt);
            costGradingPO.setRepairCost(repairCost);
            costGradingPO.setDayAvgDeposit(dayAvgAmt);
            costGradingPO.setCreditCardAmt(creditCardAmt);
            costGradingPO.setMctCountRatio(mctCountRatio);
            costGradingPO.setWanYuanRepairRatio(wanyuanRepairRatio);
            costGradingPO.setMctDvgCost(mctDvgCost);
            costGradingPO.setCreditCardRatio(creditCardRatio);
            costGradingPOList.add(costGradingPO);
        }
        return costGradingPOList;
    }

    /**
     * 划断分批规则:1-6同批次,7-11同批次,12-13同批次,14-16同批次,17-20同批次
     * @params: gradingNo 分档编号
     * @return: com.ttg.common.enums.GradingCutOffEnum
     * @date: 2025/10/14 9:56
     * @author: chenyou
     */
    public GradingCutOffEnum getCutOffEnum(Integer gradingNo){
        return GradingCutOffEnum.getByCode(gradingNo);
    }

    public void sum1(List<CostGradingPO> costGradingPOList, MerchDimTypeEnum merchDimTypeEnum, String month){
        //分档1-13小计
        List<CostGradingPO> sublist_1_13 =
                costGradingPOList.stream().filter(o -> o.getCutOffEnum().equals(GradingCutOffEnum.CUT_OFF_1_6)
                        || o.getCutOffEnum().equals(GradingCutOffEnum.CUT_OFF_7_11)
                        || o.getCutOffEnum().equals(GradingCutOffEnum.CUT_OFF_12_13)).collect(Collectors.toList());

        Integer Bsum1 = 0;
        BigDecimal Csum1 = BigDecimal.ZERO;
        BigDecimal Dsum1 = BigDecimal.ZERO;
        BigDecimal Esum1 = BigDecimal.ZERO;

        for(CostGradingPO vo:sublist_1_13){
            //Bsum1 = B1+B2+B3+ … +B13
            Bsum1 = Bsum1 + vo.getMctCount();
            //Csum1 = C1+C2+C3+ … +C13
            Csum1 = BigDecimalUtils.add(Csum1,vo.getRepairCost());
            //Dsum1 = D1+D2+D3+ … +D13
            Dsum1 = BigDecimalUtils.add(Dsum1,vo.getDayAvgDeposit());
            //Esum1 = E1+E2+E3+ … +E13
            Esum1 = BigDecimalUtils.add(Esum1,vo.getMctCountRatio());
        }
        BigDecimal tradeAmt1 = new BigDecimal(sublist_1_13.stream().mapToLong(o -> o.getTradeAmt()==null?0:o.getTradeAmt().longValue()).sum());
        BigDecimal creditCardAmt1 = new BigDecimal(sublist_1_13.stream().mapToLong(o -> o.getCreditCardAmt()==null?0:o.getCreditCardAmt().longValue()).sum());
        //Fsum1 = Csum1*10000/(1-13档全部商户总流水)
        BigDecimal Fsum1 = BigDecimalUtils.div(BigDecimalUtils.mul(Csum1,10000),tradeAmt1,2);
        //Gsum1 = Csum1/Bsum1
        BigDecimal Gsum1 = BigDecimalUtils.div(Csum1,Bsum1,2);
        //Hsum1 = 1-13档全部商户信用卡交易金额占比
        BigDecimal Hsum1 =  BigDecimalUtils.div(creditCardAmt1,tradeAmt1,4);
        //本地线程保存,方便后续使用
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Bsum1",new BigDecimal(Bsum1));
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Csum1",Csum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Dsum1",Dsum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Esum1",Esum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Fsum1",Fsum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Gsum1",Gsum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Hsum1",Hsum1);
    }

    public void sum2(List<CostGradingPO> costGradingPOList, MerchDimTypeEnum merchDimTypeEnum, String month){
        List<CostGradingPO> sublist_14_20 =
                costGradingPOList.stream().filter(o -> o.getCutOffEnum().equals(GradingCutOffEnum.CUT_OFF_14_16)
                        || o.getCutOffEnum().equals(GradingCutOffEnum.CUT_OFF_17_20)).collect(Collectors.toList());
        Integer Bsum2 = 0;
        BigDecimal Csum2 = BigDecimal.ZERO;
        BigDecimal Dsum2 = BigDecimal.ZERO;
        BigDecimal Esum2 = BigDecimal.ZERO;

        for(CostGradingPO vo:sublist_14_20){
            //Bsum2 = B14+B15+ … +B20
            Bsum2 = Bsum2 + vo.getMctCount();
            //Csum2 = C14+C15+ … +C20
            Csum2 = BigDecimalUtils.add(Csum2,vo.getRepairCost());
            //Dsum2 = D14+D15+ … +D20
            Dsum2 = BigDecimalUtils.add(Dsum2,vo.getDayAvgDeposit());
            //Esum2 = E14+E15+ … +E20
            Esum2 = BigDecimalUtils.add(Esum2,vo.getMctCountRatio());
        }
        BigDecimal tradeAmt2 = new BigDecimal(sublist_14_20.stream().mapToLong(o -> o.getTradeAmt()==null?0:o.getTradeAmt().longValue()).sum());
        BigDecimal creditCardAmt2 = new BigDecimal(sublist_14_20.stream().mapToLong(o -> o.getCreditCardAmt()==null?0:o.getCreditCardAmt().longValue()).sum());
        //Fsum2 = Csum2*10000/(14-20档全部商户总流水)
        BigDecimal Fsum2 = BigDecimalUtils.div(BigDecimalUtils.mul(Csum2,10000),tradeAmt2,2);
        //Gsum2 = Csum2/Bsum2
        BigDecimal Gsum2 = BigDecimalUtils.div(Csum2,Bsum2,2);
        //Hsum2 = 14-20档全部商户信用卡交易金额占比
        BigDecimal Hsum2 =  BigDecimalUtils.div(creditCardAmt2,tradeAmt2,4);
        //本地线程保存,方便后续使用
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Bsum2",new BigDecimal(Bsum2));
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Csum2",Csum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Dsum2",Dsum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Esum2",Esum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Fsum2",Fsum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Gsum2",Gsum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Hsum2",Hsum2);
    }

    private void sum3(List<CostGradingPO> costGradingPOList, MerchDimTypeEnum merchDimTypeEnum, String month){
        BigDecimal tradeAmt3 = new BigDecimal(costGradingPOList.stream().mapToLong(o -> o.getTradeAmt()==null?0:o.getTradeAmt().longValue()).sum());
        BigDecimal creditCardAmt3 = new BigDecimal(costGradingPOList.stream().mapToLong(o -> o.getCreditCardAmt()==null?0:o.getCreditCardAmt().longValue()).sum());
        //Bsum3 = Bsum1+Bsum2
        Integer Bsum3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum1"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum2")).intValue();
        //Csum3 = Csum1+Csum2
        BigDecimal Csum3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum1"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum2"));
        //Dsum3 = Dsum1+Dsum2
        BigDecimal Dsum3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum1"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum2"));
        //Esum3 = Esum1+Esum2
        BigDecimal Esum3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Esum1"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Esum2"));
        //Fsum3 = Csum3*10000/(1-20档全部商户总流水)
        BigDecimal Fsum3 = BigDecimalUtils.div(BigDecimalUtils.mul(Csum3,10000),tradeAmt3,2);
        //Gsum3 = Csum2/Bsum2
        BigDecimal Gsum3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum2"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum2"));
        //Hsum3 = 1-20档全部商户信用卡交易金额占比
        BigDecimal Hsum3 = BigDecimalUtils.div(creditCardAmt3,tradeAmt3,4);
        //本地线程保存,方便后续使用
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Bsum3",new BigDecimal(Bsum3));
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Csum3",Csum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Dsum3",Dsum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Esum3",Esum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Fsum3",Fsum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Gsum3",Gsum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Hsum3",Hsum3);
    }

    public List<CostGradingCutoffBatchPO> cutoffBatchList(List<CostGradingPO> costGradingPOList, MerchDimTypeEnum merchDimTypeEnum, String month){
        List<CostGradingCutoffBatchPO> cutoffBatchList = new ArrayList<>();
        Map<GradingCutOffEnum,List<CostGradingPO>> cutOffEnumListMap = costGradingPOList.stream().collect(Collectors.groupingBy(o -> o.getCutOffEnum()));
        for(Map.Entry<GradingCutOffEnum,List<CostGradingPO>> entry:cutOffEnumListMap.entrySet()){
            CostGradingCutoffBatchPO cutoffBatchPO = new CostGradingCutoffBatchPO();
            GradingCutOffEnum cutOffEnum = entry.getKey();
            List<CostGradingPO> subList = entry.getValue();
            //划断贴费成本=分档内贴费成本汇总
            BigDecimal repairCost = new BigDecimal(subList.stream().mapToLong(o -> o.getRepairCost()==null?0:o.getRepairCost().longValue()).sum());
            //贴费成本占比=划断贴费成本/全体商户贴费成本汇总(Csum3)
            BigDecimal repairCostRatio = BigDecimalUtils.div(repairCost,CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum3"),4);
            //日均存款 = 分档内日均存款汇总
            BigDecimal dayAvgDeposit = new BigDecimal(subList.stream().mapToLong(o -> o.getDayAvgDeposit()==null?0:o.getDayAvgDeposit().longValue()).sum());
            //日均存款占比 = 日均存款/全体商户日均存款汇总(Dsum3)
            BigDecimal dayAvgDepositRatio = BigDecimalUtils.div(dayAvgDeposit,CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum3"),4);
            //户数 = 分档内商户数汇总
            Integer mctCount = subList.stream().mapToInt(o -> o.getMctCount()==null?0:o.getMctCount().intValue()).sum();
            //户数占比 = 户数/全体商户数(Bsum3)
            BigDecimal mctCountRatio = BigDecimalUtils.div(mctCount,CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum3"),4);
            //生成批次号
//            String batchNo = generateCostGradingBatchNo(reqDto);
            cutoffBatchPO.setCutOffEnum(cutOffEnum);
//            cutoffBatchPO.setCgcbBatchNo(batchNo);
//            cutoffBatchPO.setCgcbIntervalType(reqDto.getIntervalType());
//            cutoffBatchPO.setCgcbYear(reqDto.getYear());
//            cutoffBatchPO.setCgcbMonth(reqDto.getMonth());
//            cutoffBatchPO.setCgcbMctDimType(reqDto.getMerchDimType());
//            cutoffBatchPO.setCgcbSumFlag("single");
            cutoffBatchPO.setCutoff(cutOffEnum.getValue());
            cutoffBatchPO.setRepairCost(repairCost);
            cutoffBatchPO.setRepairCostRatio(repairCostRatio);
            cutoffBatchPO.setDayAvgDeposit(dayAvgDeposit);
            cutoffBatchPO.setDayAvgDepositRatio(dayAvgDepositRatio);
            cutoffBatchPO.setMctCount(mctCount);
            cutoffBatchPO.setMctCountRatio(mctCountRatio);
            cutoffBatchList.add(cutoffBatchPO);

            //本地线程保存,方便后续使用
            if(GradingCutOffEnum.CUT_OFF_1_6.equals(cutOffEnum)){
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum4",repairCost);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum4",repairCostRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum4",dayAvgDeposit);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum4",dayAvgDepositRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"M4",new BigDecimal(mctCount));
                CostGradingUtil.putResult(merchDimTypeEnum,month,"N4",mctCountRatio);
            }else if(GradingCutOffEnum.CUT_OFF_7_11.equals(cutOffEnum)){
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum5",repairCost);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum5",repairCostRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum5",dayAvgDeposit);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum5",dayAvgDepositRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"M5",new BigDecimal(mctCount));
                CostGradingUtil.putResult(merchDimTypeEnum,month,"N5",mctCountRatio);
            }else if(GradingCutOffEnum.CUT_OFF_12_13.equals(cutOffEnum)){
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum6",repairCost);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum6",repairCostRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum6",dayAvgDeposit);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum6",dayAvgDepositRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"M6",new BigDecimal(mctCount));
                CostGradingUtil.putResult(merchDimTypeEnum,month,"N6",mctCountRatio);
            }else if(GradingCutOffEnum.CUT_OFF_14_16.equals(cutOffEnum)){
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum7",repairCost);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum7",repairCostRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum7",dayAvgDeposit);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum7",dayAvgDepositRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"M7",new BigDecimal(mctCount));
                CostGradingUtil.putResult(merchDimTypeEnum,month,"N7",mctCountRatio);
            }else if(GradingCutOffEnum.CUT_OFF_17_20.equals(cutOffEnum)){
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum8",repairCost);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum8",repairCostRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum8",dayAvgDeposit);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum8",dayAvgDepositRatio);
                CostGradingUtil.putResult(merchDimTypeEnum,month,"M8",new BigDecimal(mctCount));
                CostGradingUtil.putResult(merchDimTypeEnum,month,"N8",mctCountRatio);
            }
        }
        return cutoffBatchList;
    }

    public void batchSum1(MerchDimTypeEnum merchDimTypeEnum,String month){
        //贴费成本 Isum1 = Isum4+Isum5+Isum6
        BigDecimal Isum1 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum4"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum5"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum6"));
        //贴费成本占比 Jsum1 = 贴费成本/全体商户贴费成本汇总(Csum3)
        BigDecimal Jsum1 = BigDecimalUtils.div(Isum1,CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum3"));
        //日均存款 Ksum1 = Ksum4+Ksum5+Ksum6
        BigDecimal Ksum1 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum4"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum5"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum6"));
        //日均存款占比 Lsum1 = 日均存款/全体商户日均存款汇总(Dsum3)
        BigDecimal Lsum1 = BigDecimalUtils.div(Ksum1,CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum3"),4);
        //户数 M1 = M4+M5+M6
        BigDecimal M1 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"M4"),CostGradingUtil.getResult(merchDimTypeEnum,month,"M5"),CostGradingUtil.getResult(merchDimTypeEnum,month,"M6"));
        //户数占比 N1 = 户数/全体商户数(Bsum3)
        BigDecimal N1 = BigDecimalUtils.div(M1,CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum3"),4);
        //本地线程保存,方便后续使用
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum1",Isum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum1",Jsum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum1",Ksum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum1",Lsum1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"M1",M1);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"N1",N1);
    }

    public void batchSum2(MerchDimTypeEnum merchDimTypeEnum,String month){
        //贴费成本 Isum2 = Isum7+Isum8
        BigDecimal Isum2 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum7"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum8"));
        //贴费成本占比 Jsum2 = 贴费成本/全体商户贴费成本汇总(Csum3)
        BigDecimal Jsum2 = BigDecimalUtils.div(Isum2,CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum3"));
        //日均存款 Ksum2 = Ksum7+Ksum8
        BigDecimal Ksum2 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum7"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum8"));
        //日均存款占比 Lsum2 = 日均存款/全体商户日均存款汇总(Dsum3)
        BigDecimal Lsum2 = BigDecimalUtils.div(Ksum2,CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum3"),4);
        //户数 M2 = M7+M8
        BigDecimal M2 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"M7"),CostGradingUtil.getResult(merchDimTypeEnum,month,"M8"));
        //户数占比 N2 = 户数/全体商户数(Bsum3)
        BigDecimal N2 = BigDecimalUtils.div(M2,CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum3"),4);
        //本地线程保存,方便后续使用
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum2",Isum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum2",Jsum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum2",Ksum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum2",Lsum2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"M2",M2);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"N2",N2);
    }

    public void batchSum3(MerchDimTypeEnum merchDimTypeEnum,String month){
        //贴费成本 Isum3 = Isum1+Isum2
        BigDecimal Isum3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum1"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum2"));
        //贴费成本占比 Jsum3 = 贴费成本/全体商户贴费成本汇总(Csum3)
        BigDecimal Jsum3 = BigDecimalUtils.div(Isum3,CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum3"));
        //日均存款 Ksum3 = Ksum1+Ksum2
        BigDecimal Ksum3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum1"),CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum2"));
        //日均存款占比 Lsum3 = 日均存款/全体商户日均存款汇总(Dsum3)
        BigDecimal Lsum3 = BigDecimalUtils.div(Ksum3,CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum3"),4);
        //户数 M3 = M1+M2
        BigDecimal M3 = BigDecimalUtils.add(CostGradingUtil.getResult(merchDimTypeEnum,month,"M1"),CostGradingUtil.getResult(merchDimTypeEnum,month,"M2"));
        //户数占比 N3 = 户数/全体商户数(Bsum3)
        BigDecimal N3 = BigDecimalUtils.div(M3,CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum3"),4);
        //本地线程保存,方便后续使用
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Isum3",Isum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Jsum3",Jsum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Ksum3",Ksum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"Lsum3",Lsum3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"M3",M3);
        CostGradingUtil.putResult(merchDimTypeEnum,month,"N3",N3);
    }

    public void bulidCostGradingSumInfo(List<CostGradingPO> costGradingPOList, MerchDimTypeEnum merchDimTypeEnum, String month){
        //小计1
        CostGradingPO sum1 = new CostGradingPO();
//        sum1.setCmcgIntervalType(reqDto.getIntervalType());
//        sum1.setCmcgYear(reqDto.getYear());
//        sum1.setCmcgMonth(reqDto.getMonth());
//        sum1.setCmcgMctDimType(reqDto.getMerchDimType());
        sum1.setSumFlag("sum1");
        sum1.setMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum1").intValue());
        sum1.setRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum1"));
        sum1.setDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum1"));
        sum1.setMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Esum1"));
        sum1.setWanYuanRepairRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Fsum1"));
        sum1.setMctDvgCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Gsum1"));
        sum1.setCreditCardRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Hsum1"));
        costGradingPOList.add(sum1);

        //小计2
        CostGradingPO sum2 = new CostGradingPO();
//        sum2.setCmcgIntervalType(reqDto.getIntervalType());
//        sum2.setCmcgYear(reqDto.getYear());
//        sum2.setCmcgMonth(reqDto.getMonth());
//        sum2.setCmcgMctDimType(reqDto.getMerchDimType());
        sum2.setSumFlag("sum2");
        sum2.setMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum2").intValue());
        sum2.setRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum2"));
        sum2.setDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum2"));
        sum2.setMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Esum2"));
        sum2.setWanYuanRepairRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Fsum2"));
        sum2.setMctDvgCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Gsum2"));
        sum2.setCreditCardRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Hsum2"));
        costGradingPOList.add(sum2);

        //合计
        CostGradingPO sum3 = new CostGradingPO();
//        sum3.setCmcgIntervalType(reqDto.getIntervalType());
//        sum3.setCmcgYear(reqDto.getYear());
//        sum3.setCmcgMonth(reqDto.getMonth());
//        sum3.setCmcgMctDimType(reqDto.getMerchDimType());
        sum3.setSumFlag("sum3");
        sum3.setMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"Bsum3").intValue());
        sum3.setRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Csum3"));
        sum3.setDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Dsum3"));
        sum3.setMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Esum3"));
        sum3.setWanYuanRepairRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Fsum3"));
        sum3.setMctDvgCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Gsum3"));
        sum3.setCreditCardRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Hsum3"));
        costGradingPOList.add(sum3);
    }

    public void bulidCutoffBatchSumInfo(List<CostGradingCutoffBatchPO> cutoffBatchList, MerchDimTypeEnum merchDimTypeEnum, String month){
        //小计1
        CostGradingCutoffBatchPO batchSum1 = new CostGradingCutoffBatchPO();
//        batchSum1.setCgcbBatchNo(generateCostGradingBatchNo(reqDto));
//        batchSum1.setCgcbIntervalType(reqDto.getIntervalType());
//        batchSum1.setCgcbYear(reqDto.getYear());
//        batchSum1.setCgcbMonth(reqDto.getMonth());
//        batchSum1.setCgcbMctDimType(reqDto.getMerchDimType());
        batchSum1.setSumFlag("sum1");
        batchSum1.setRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum1"));
        batchSum1.setRepairCostRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Jsum1"));
        batchSum1.setDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum1"));
        batchSum1.setDayAvgDepositRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Lsum1"));
        batchSum1.setMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"M1").intValue());
        batchSum1.setMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"N1"));
        cutoffBatchList.add(batchSum1);
        //小计2
        CostGradingCutoffBatchPO batchSum2 = new CostGradingCutoffBatchPO();
//        batchSum2.setCgcbBatchNo(generateCostGradingBatchNo(reqDto));
//        batchSum2.setCgcbIntervalType(reqDto.getIntervalType());
//        batchSum2.setCgcbYear(reqDto.getYear());
//        batchSum2.setCgcbMonth(reqDto.getMonth());
//        batchSum2.setCgcbMctDimType(reqDto.getMerchDimType());
        batchSum2.setSumFlag("sum2");
        batchSum2.setRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum2"));
        batchSum2.setRepairCostRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Jsum2"));
        batchSum2.setDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum2"));
        batchSum2.setDayAvgDepositRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Lsum2"));
        batchSum2.setMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"M2").intValue());
        batchSum2.setMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"N2"));
        cutoffBatchList.add(batchSum2);
        //合计
        CostGradingCutoffBatchPO batchSum3 = new CostGradingCutoffBatchPO();
//        batchSum3.setCgcbBatchNo(generateCostGradingBatchNo(reqDto));
//        batchSum3.setCgcbIntervalType(reqDto.getIntervalType());
//        batchSum3.setCgcbYear(reqDto.getYear());
//        batchSum3.setCgcbMonth(reqDto.getMonth());
//        batchSum3.setCgcbMctDimType(reqDto.getMerchDimType());
        batchSum3.setSumFlag("sum3");
        batchSum3.setRepairCost(CostGradingUtil.getResult(merchDimTypeEnum,month,"Isum3"));
        batchSum3.setRepairCostRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Jsum3"));
        batchSum3.setDayAvgDeposit(CostGradingUtil.getResult(merchDimTypeEnum,month,"Ksum3"));
        batchSum3.setDayAvgDepositRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"Lsum3"));
        batchSum3.setMctCount(CostGradingUtil.getResult(merchDimTypeEnum,month,"M3").intValue());
        batchSum3.setMctCountRatio(CostGradingUtil.getResult(merchDimTypeEnum,month,"N3"));
        cutoffBatchList.add(batchSum3);
    }


    public List<Map<String, Object>> bulidMerchDataList(List<CostManageMerchTradeMonth> resultList){
        List<Map<String, Object>> partDataList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(resultList)) {
            for(int i = 0; i < resultList.size(); i++){
                CostManageMerchTradeMonth vo = resultList.get(i);
                Map<String, Object> data = new HashMap<>();
                data.put("serialNumber", i + 1);

                // 行业分类 - 需要嵌套结构
                List<Map<String, Object>> industryList = new ArrayList<>();
                Map<String, Object> industryMap = new HashMap<>();
                industryMap.put("mainCategory", "待定");
                industryMap.put("subCategory", "待定");
                industryList.add(industryMap);
                data.put("industry",industryList);

                // 商户情况 - 需要嵌套结构
                List<Map<String, Object>> merchantList = new ArrayList<>();
                Map<String, Object> merchantMap = new HashMap<>();
                merchantMap.put("mctNo", vo.getMtmMctNo());
                merchantMap.put("mctName", "待定");
                merchantMap.put("custNo", "待定");
                merchantList.add(merchantMap);
                data.put("merchantInfo",merchantList);

                //清算成本
                data.put("clearCost", vo.getMtmClearCost());
                //贴费成本
                data.put("repairCost", vo.getMtmRepairCost());
                //日均存款
                data.put("dayAvgDeposit", vo.getMtmDayAvgAmt());
                //万元补贴水平
                data.put("wanYuanRepairRatio", vo.getMtmWanYuanRepairRatio());
                partDataList.add(data);
            }
        }
        return partDataList;
    }

    public void workbookExport(IWriter<Workbook> workbookIWriter, HttpServletResponse response, String fileName, String fileType) {
        try (ServletOutputStream outputStream = response.getOutputStream(); Workbook workbook = workbookIWriter.get()) {
            if (workbook != null) {
                response.setCharacterEncoding("UTF-8");
                response.setHeader("content-Type", "application/vnd.ms-excel");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + fileType, "UTF-8"));
                response.setHeader("Access-Control-Expose-Headers", "filename");
                response.setHeader("filename", URLEncoder.encode(fileName + fileType, "UTF-8"));
                workbook.write(outputStream);
            }
        } catch (IOException e) {
            log.error("导出异常{}", fileName, e);
            throw new BaseException(ErrorCodeEnums.SYSTEM_ERROR.getErrcode(), "报表导出异常");
        }
    }
}
